package cn.com.cifi.mars.service;

import cn.com.cifi.mars.bean.bo.*;
import cn.com.cifi.mars.bean.dto.*;
import cn.com.cifi.mars.bean.vo.signPlan.FullPathVo;
import cn.com.cifi.mars.bean.vo.signPlan.SigPlanPreviewVo;
import cn.com.cifi.mars.bean.vo.signPlan.SignPlanVersionVo;
import cn.com.cifi.mars.bean.vo.signPlan.SignProductVo;
import cn.com.cifi.mars.bean.vo.signPlan.req.SignPlanDetailParam;
import cn.com.cifi.mars.bean.vo.signPlan.req.SignPlanOaParam;
import cn.com.cifi.mars.bean.vo.signPlan.signOverall.OverallSignPlanVo;
import cn.com.cifi.mars.entity.*;
import cn.com.cifi.mars.entity.common.IdmUser;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 签约计划版本表 服务类
 * </p>
 *
 * @author yyd
 * @since 2019-11-08
 */
public interface SignPlanVersionService extends IService<SignPlanVersion> {

    /**
     * 创建签约计划版本
     * @param projectFid  分期id
     * @param versionType 版本类型
     * @param alias    创建人
     */
    String createSignPlan(String projectFid, String versionType,String versionIdentify,String alias);

    /**
     * 异常新建签约计划版本
     * @param projectFid  分期id
     * @param versionType 版本类型
     * @param userName    创建人
     * @return
     */
    String exceptionCreate(String projectFid, String versionType,String versionIdentify, String userName);

    /**
     * 获取指定时间中的签约供货详情
     * @param spvsdList 签约供货详情列表
     * @param yearMonth （年-月）字符串
     * @return
     */
    List<SignSupplyDetailBO> getSignPlanVersionSupplyDetailBySuppluTime(List<SignSupplyDetailBO> spvsdList, String yearMonth);

    /**
     * 删除签约计划版本
     */
    String deleteSignPlanVersion(String versionId,String alias);

    /**
     * 查询签约计划版本展示
     */
    SignPlanVersionVo getSignPlanVersion(String versionId, String year);

    /**
     * 查询签约版本全路径名称与来源版本全路径名称
     */
    FullPathVo getSignFullPath(String versionId);

    /**
     * 保存产品构成签约计划
     */
    String saveProductSignPlan(SignPlanDetailParam signPlanDetailParam, String userName);

    /**
     * 查询签约版本全路径名称与来源版本全路径名称列表
     */
    List<FullPathVo> getSignFullPathList(String projectFid, String versionType);

    /**
     * 查询该分期最新版本
     */
    String getNewVersionType(String projectFid);

    /**
     * 接收销管系统推送的签约计划数据
     */
    Map<Boolean,String> insertDynamicSignPlanVersion(String stageId);

    /**
     * 分期是否存在可售
     * @param projectfId
     * @return
     */
    boolean getStageIsSaly(String projectfId);

    /**
     * type :0  查询当月供货计划详细数据（总是取计划，对于当月之前已经实际供货的楼栋，不参与计算）
     * type :1  查询当年供货计划详细数据（总是取计划，对于当年之前已经实际供货的楼栋，不参与计算）
     * @param supplyDetailList 供货详情列表
     * @param dateTime 查询时间
     * @param isParking 是否车位楼栋
     * @param type 查询类型（0:月 ,1:年）
     * @return
     */
    SignProductDetailBO getSupplyPlanDetail(List<SignPlanVersionSupplyDetail> supplyDetailList, LocalDateTime dateTime, int isParking, int type);

    /**
     * 查询当月供货实际详情数据
     *
     * @param supplyDetailList 签约计划供货列表
     * @param dateTime         指定时间
     * @param isParking        是否车位楼栋
     * @return
     */
    SignProductDetailBO getSupplyActualDetail(List<SignPlanVersionSupplyDetail> supplyDetailList, LocalDateTime dateTime, int isParking);

    /**
     * 查询当月供货金额(有实际取月度实际供货金额，无实际取计划金额)
     *
     * @param supplyDetailList 供货详情列表
     * @param dateTime         指定时间
     * @param isParking        是否车位楼栋
     * @param type             查询类型（0 : 查询当年, 1 : 查询当月）
     * @return
     */
    SignProductDetailBO getSupplyDetail(List<SignSupplyDetailBO> supplyDetailList, LocalDateTime dateTime, int isParking, int type);

    /**
     * 查询指定时间签约计划详细数据
     *
     * @param signPlanVersionDetailList 签约计划详情列表
     * @param dateTime                  指定时间
     * @return
     */
    SignPlanVersionDetail getSignPlanDetailByTime(List<SignPlanVersionDetail> signPlanVersionDetailList, LocalDateTime dateTime);

    /**
     * 查询指定时间年初存货实际签约金额
     * @param signPlanVersionDetailList 签约计划详情列表
     * @param dateTime                  指定时间
     * @param isParking                是否车位楼栋
     * @return
     */
    SignProductDetailBO getYearEalySignSumPriceActualByTime(List<SignPlanVersionDetail> signPlanVersionDetailList, LocalDateTime dateTime, int isParking);

    /**
     * 修改数值格式 金额单位万元
     * @param signPlanVersionDetailDtoList
     */
    List<SignPlanVersionDetailDto> unitConversion(List<SignPlanVersionDetailDto> signPlanVersionDetailDtoList);

    /**
     * 查询签约计划审批预览
     */
    SigPlanPreviewVo getApprovalPreview(String projectId, String billId);


    /**
     * 判断签约版本中是否存在未编制完成的数据
     * @param versionIdList
     * @return
     */
    boolean isEstablishment(List<String> versionIdList);

    //查询全盘最新签约计划版本id列表映射
    Map<String,List<String>> getOverallSignVersionListMap();

    /**
     * 查询全盘签约计划版本列表
     * @param projectId 项目id
     * @return
     */
    List<String> getOverallSignVersionList(String projectId);

    //查询全盘项目下的所有分期最新的签约计划数据
    SignPlanVersion getOverallByProjectf(String projectfId);

    /**
     * 查询指定时间全盘最新签约计划版本列表
     * @param projectId 项目id
     * @param yearMonth yyyy-MM
     * @return
     */
    List<String> getOverallSignVersionList(String projectId,String yearMonth);

    /**
     * 获取版本列表中全盘签约数据
     * @param projectId 项目id
     * @param year 年份
     * @param code 筛选条件（业态.产品构成）
     * @param versionIds 签约版本id列表
     * @return
     */
    List<SignPlanVersionDetailDto> getOverallSignPlanListDate(String projectId, String year, String code, List<String> versionIds);

    /**
     * 版本列表全周期年份列表
     * @param versionIds 签约版本列表
     * @return
     */
    List<String> getDateList(List<String> versionIds);

    /**
     * 获取全盘年度签约目标
     * 1、非预算版(战规、动态: 已过月份取实际,未过月份取计划;若是投资版: 全取计划)
     * 2、预算版（查看来源版本类型,参考1）
     * @param versionIds 版本id集合
     * @param yearMonth 审批发起时间
     * @param type 0:调整前;1:调整后
     * @return
     */
    BigDecimal getYearSignTarget(List<String> versionIds, String yearMonth, int type);

    /**
     * 签约审批-提交到OA审批
     */
    String submitToOA(SignPlanOaParam param, IdmUser user);

    /**
     * 签约检查是否可以提交审批
     */
    int checkApprovedVersionIsNull(String projectId);

    /**
     * 根据projectId查询需要审批的项目的分期
     *
     * @param projectId
     * @return
     */
    List<SignPlanVersion> selectApprovedProject(String projectId);

    /**
     * 审批校验 查询是否存在待编制或者审批中的版本
     *
     * @param projectId
     * @return
     */
    int checkApprovedVersion(String projectId);

    /**
     * 签约计划审批通过后的 添加版本Id到审批记录信息中
     *
     * @param successIds
     * @param versionId
     */
    void insertApproved(List<String> successIds, String versionId);

    /**
     * 判断供货计划版本是否在签约中被有效使用
     *
     * @param supplyVersionId
     * @return
     */
    boolean supplyBoolean(String supplyVersionId);


    /**
     * 货值版本是否在签约中被有效使用
     *
     * @param versionIds 货值版本id列表
     * @return
     */
    Map<String, Boolean> priceBoolean(List<String> versionIds);

    /**
     * 查询产品构成列表
     * @param versionId 版本id
     * @return
     */
    List<SignProductVo> getProductList(String versionId);

    /**
     * 查询全盘签约概览
     * @param versionId 版本id
     * @param year 年份
     * @param month 月份
     * @return
     */
    List<ProjectProductBO> getProjectProductList(String versionId, String year,String month);

    /**
     * 获取项目全盘签约计划报表数据
     * @param projectId 项目id
     * @param versionIds 版本id列表
     * @param startAndEndTimeBO 开始与结束时间
     * @return
     */
    List<OverallSignPlanVo> getOverallSignPlanReport(String projectId, List<String> versionIds,StartAndEndTimeBO startAndEndTimeBO);

    /**
     * 设置考核版
     * @param versionId 版本id
     * @return
     */
    String settingsAssessmentVersion(String versionId);

    /**
     * 供货考核版修改，更新签约考核版
     * @param versionId 供货版本id
     * @param projectfId 分期id
     */
    void updateAssessmentVersion(String versionId,String projectfId);

    /**
     * 全盘签约计划报表精度修改
     * @param voList
     */
    void updateOverallSignPlanVoAccuracy(List<OverallSignPlanVo> voList);

    /**
     * 查询最早供货时间与最晚签约时间
     * @param versionIds
     * @return
     */
    StartAndEndTimeBO getStartAndEndTime(List<String> versionIds);

    /**
     * 根据id查询签约版本
     * @param versionId
     * @return
     */
    SignPlanVersion selectById(String versionId);


    /**
     * 签约代办处理
     * @param versionId 供货版本id
     */
    void signNoticeDispose(String versionId);

    /**
     * 消除代办
     * @param versionId 代办关联id
     * @param operatorType 代办处理方式
     * @param handUser 处理人
     */
    String deleteTodoInfo(String versionId, String operatorType, IdmUser handUser);

    /**
     * 查询签约计划全部项目
     * @return
     */
    Set<String> selectProjectIdAll();

    /**
     * 审批单查看内容缓存处理
     * @param businesskey 审批单id
     * @param approvedState 审批单状态
     */
    void handApprovalBillBuffer(String businesskey, String approvedState);

    /**
     * 接OA审批消息后会操作
     * @param versionId 版本id
     * @param state 版本状态
     * @param eventType 审批事件类型
     */
    void successSpproved(String versionId ,String state,Integer eventType);

    //是否战规后
    boolean isAfterWarplan(String projectFId);

    /**
     * 计算下个月月初存货
     * @param spvdBO 月初存货
     * @param signInitializeBO 签约计划初始化参数
     */
    void calculateMonthlyInventory(SignPlanVersionDetailBO spvdBO, SignInitializeBO signInitializeBO);

    /**
     * 初始化签约计划详情共有数据模板
     * @param spvdTemplate 签约计划详情模板
     * @param spvsd 签约供货详情
     * @param group 组团信息
     * @return
     */
    SignPlanVersionDetail initializeSignDetailTemplate(SignPlanVersionDetail spvdTemplate, SignPlanVersionSupplyDetail spvsd, SignPlanVersionSupplyDetail group);

    /**
     * 获取实际签约数据相关参数
     * @param ssdBOList 签约供货详情
     * @param versionType 版本类型
     * @param projectFid 分期id
     * @return
     */
    SignActualCalculateBO getSignActualCalculateBO(List<SignSupplyDetailBO> ssdBOList, String versionType, String projectFid);

    /**
     * 初始化本月新供签约数据
     * @param signInitializeBO 签约计划初始化参数
     * @param signActualCalculateBO 签约实际计算参数
     */
    void initializeEarlySignDetail(SignInitializeBO signInitializeBO, SignActualCalculateBO signActualCalculateBO);

    /**
     * 签约供货详情列表转换
     * 有实际取实际，无实际取计划
     * @param spvsdList 签约供货详情列表
     * @return
     */
    List<SignSupplyDetailBO> switchSignSupplyDetailBO(List<SignPlanVersionSupplyDetail> spvsdList);

    /**
     * 获取指定时间的楼栋列表
     *
     * @param ssdBOList 签约供货详情列表
     * @param time      指定时间
     * @param type      查询类型（0-小于指定年月,1-等于指定年月））
     * @return
     */
    List<String> getBuildingListbySuppluTimeActual(List<SignSupplyDetailBO> ssdBOList, LocalDateTime time, int type);

    /**
     * 根据楼栋列表查询明源签约数据
     * @param mymSignList 明源签约记录列表
     * @param buildings   楼栋列表
     * @param dateTime    指定时间
     * @return
     */
    ContractDto getMymSignList(List<MymContractDto> mymSignList, List<String> buildings, LocalDateTime dateTime);

    /**
     * 根据楼栋列表查询nos签约数据
     * @param nosSigningList nos签约记录列表
     * @param buildings      楼栋列表
     * @param dateTime       指定时间
     * @return
     */
    NosSignDto getNosSignList(List<NosTradedataDto> nosSigningList, List<String> buildings, LocalDateTime dateTime);

    /**
     * 查询门户代办
     * @param id 分期id+版本类型code
     * @return
     */
    PortalTodo getPortalTodo(String id);

    /**
     * 保存版本日志
     * @param versionId
     * @param event
     * @param beforeState
     * @param alias
     * @param title
     * @param content
     */
    void saveVersionLog(String versionId, String event, String beforeState, String alias, String title, String content);

    void updateState(List<String> versionIds, String versionState, IdmUser user);
    //是否售罄版本
    boolean getIsSoldOutVersion(SignPlanVersion signPlanVersion);
}
